package com.bridgeintelligent.tag.engine.parse;

import com.bridgeintelligent.tag.engine.api.BaseCode;
import com.bridgeintelligent.tag.engine.api.DimInfo;
import com.bridgeintelligent.tag.engine.api.DimItemInfo;
import com.bridgeintelligent.tag.engine.api.rsp.IndexRsp;
import com.bridgeintelligent.tag.engine.core.cache.CacheConfig;
import com.bridgeintelligent.tag.engine.core.cache.CacheUtils;
import org.apache.commons.collections.CollectionUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;

import java.util.*;

/**
 * Created by JackCheung on 2019/10/28 5:54 PM.
 */
public class IndexParse extends BaseParse {

    /**
     * 创建聚合分析返回数据
     *
     * @param searchResponses searchResponses
     * @param fields 字段集
     * @return IndexRsp
     */
    public static IndexRsp create(List<SearchResponse> searchResponses, List<String> fields) {
        Set<String> set = new HashSet<>(fields);
        IndexRsp indexRsp = new IndexRsp();
        indexRsp.setCode(BaseCode.SUCCESS);
        IndexRsp.DataRsp dataRsp = new IndexRsp.DataRsp();
        List<IndexRsp.DataRsp.DataRspChild> list = new ArrayList<>(searchResponses.size());
        searchResponses.forEach(searchResponse -> {
            if (null != searchResponse) {
                if (CollectionUtils.isEmpty(set)) {
                    IndexRsp.DataRsp.DataRspChild dataRspChild = new IndexRsp.DataRsp.DataRspChild();
                    dataRspChild.setTotalCount(searchResponse.getHits().getTotalHits().value);
                    list.add(dataRspChild);
                } else {
                    Aggregations aggregations = searchResponse.getAggregations();
                    list.add(parseHandler(aggregations, new ArrayList<>(set)));
                }
            } else {
                list.add(new IndexRsp.DataRsp.DataRspChild(0L, null));
            }
        });
        dataRsp.setList(list);
        indexRsp.setData(dataRsp);
        return indexRsp;
    }

    private static IndexRsp.DataRsp.DataRspChild parseHandler(Aggregations aggregations, ArrayList<String> fields) {
        String indexField = fields.get(0);
        Terms byAgeAggregation = aggregations.get(indexField);
        List<IndexRsp.DataRsp.DataRspChild.RspDetail> list = new ArrayList<>();
        for (Terms.Bucket buck : byAgeAggregation.getBuckets()) {
            IndexRsp.DataRsp.DataRspChild.RspDetail rspDetail = new IndexRsp.DataRsp.DataRspChild.RspDetail();
            String dimName = Optional
                    .ofNullable((DimInfo) CacheUtils.getCacheInfo(CacheConfig.DIM_INFO, indexField))
                    .map(DimInfo::getDimName)
                    .orElse(indexField);
            String showName = Optional
                    .ofNullable((DimItemInfo) CacheUtils.getCacheInfo(CacheConfig.DIM_ITEM_INFO, String.format(GROUP_FORMAT, indexField, buck.getKey())))
                    .map(DimItemInfo::getDimItemName)
                    .orElse(buck.getKey().toString());
            rspDetail.setName(String.format(GROUP_FORMAT, dimName, showName));
            rspDetail.setTotalCount(buck.getDocCount());
            int size = buck.getAggregations().getAsMap().size();
            if (size != 0) {
                fetchChild(rspDetail, fields, buck);
            }
            list.add(rspDetail);
        }
        IndexRsp.DataRsp.DataRspChild dataRspChild = new IndexRsp.DataRsp.DataRspChild();
        dataRspChild.setContent(list);
        return dataRspChild;
    }

    private static void fetchChild(IndexRsp.DataRsp.DataRspChild.RspDetail rspDetail, ArrayList<String> fields, Terms.Bucket buck) {
        List<IndexRsp.DataRsp.DataRspChild.RspDetail> child = new ArrayList<>();
        String indexFieldChild = fields.get(1);
        Terms termsChild = buck
                .getAggregations()
                .get(indexFieldChild);
        for (Terms.Bucket buckChild : termsChild.getBuckets()) {
            IndexRsp.DataRsp.DataRspChild.RspDetail rspDetailChild = new IndexRsp.DataRsp.DataRspChild.RspDetail();
            String dimNameChild = Optional
                    .ofNullable((DimInfo) CacheUtils.getCacheInfo(CacheConfig.DIM_INFO, indexFieldChild))
                    .map(DimInfo::getDimName)
                    .orElse(indexFieldChild);
            String showNameChild = Optional
                    .ofNullable((DimItemInfo) CacheUtils.getCacheInfo(CacheConfig.DIM_ITEM_INFO, String.format(GROUP_FORMAT, indexFieldChild, buckChild.getKey())))
                    .map(DimItemInfo::getDimItemName)
                    .orElse(buckChild.getKey().toString());
            rspDetailChild.setName(String.format(GROUP_FORMAT, dimNameChild, showNameChild));
            rspDetailChild.setTotalCount(buckChild.getDocCount());
            child.add(rspDetailChild);
        }
        rspDetail.setChild(child);
    }
}
